import io from 'socket.io-client'
import cookie from 'js-cookie'
import napi from '@/api/napi'
import { wsHost } from '@/config'

let socketInstance = null

export default {
  namespaced: true,
  state: {
    chatList: [],
    msgMap: {},
    newFriend: [],
    friend: []
  },
  mutations: {
    setChatList(state, data) {
      state.chatList = data
    },
    setMsgMap(state, data) {
      state.msgMap = data
    },
    setNewFriend(state, data) {
      state.newFriend = data
    },
    setFriend(state, data) {
      state.friend = data
    }
  },
  actions: {
    /**
     * 获取历史消息
     * @param {*} param0
     * @param {*} param1
     * @returns
     */
    getHistory({ commit, state, rootState }, { r_user, room_id, pageIndex, pageSize, init, is_group = 0 }) {
      return napi.getHistory({
        s_user: state.userInfo.id,
        r_user: r_user,
        pageIndex,
        pageSize,
        is_group,
        room_id
      }).then(res => {
        const list = res.data.list
        if (init) {
          state.msgMap[r_user] = list
        } else {
          state.msgMap[r_user] = list.concat([...state.msgMap[r_user]])
        }
        commit('setMsgMap', JSON.parse(JSON.stringify(state.msgMap)))
        return list
      })
    },

    /**
     * 初始化 socket
     * @param {*} param0
     * @returns
     */
    initSocket({ state, dispatch, commit, rootState }) {
      const uInfo = rootState.user.userInfo
      if (socketInstance && socketInstance.connected) {
        return
      }

      const token = cookie.get('token')
      const socket = socketInstance = io(wsHost, {
        query: {
          room: 'demo',
          token: token || Math.random()
        },
        transports: ['websocket']
      })

      socket.on('connect', function() {
        console.info('connect success')
        socket.emit('online', {
          payload: {
            userId: uInfo.id
          }
        })
      })

      // 聊天列表
      socket.on('chat-list', ({ payload }) => {
        commit('setChatList', payload.list)
      })

      // 聊天消息列表
      socket.on('chat-item-list', ({ payload }) => {
        const partnerId = payload.partner_id
        const msgMap = state.msgMap
        msgMap[partnerId] = msgMap[partnerId] || []
        msgMap[partnerId] = msgMap[partnerId].concat(payload.list)
        // 这里肯定是存在的
        // 可能有BUG，当 chat-list 消息比 chat-item-list 消息后接收到时
        const current = state.chatList.find(el => el.partner_id == partnerId)
        if (current) {
          // 存在 => 更新
          Object.assign(current, {
            content: payload.list[payload.list.length - 1].content,
            create_time: payload.list[payload.list.length - 1].create_time
          })
        }
        if (payload.is_group) {
          current.user_nickname = payload.list[payload.list.length - 1].nickname
        }
        commit('setMsgMap', JSON.parse(JSON.stringify(msgMap)))
        commit('setChatList', JSON.parse(JSON.stringify(state.chatList)))
      })

      // 私信
      socket.on('news', ({ payload }) => {
        console.info('news', payload)
        dispatch('handleNewMsg', payload)
      })

      // 群消息
      socket.on('room-news', ({ payload }) => {
        console.info('room-news', payload)
        dispatch('handleRoomNewMsg', payload)
      })

      // 好友申请
      socket.on('friendApply', ({ payload }) => {
        console.info('friendApply', payload)
        commit('setNewFriend', state.newFriend.concat(payload))
      })

      // 新好友
      socket.on('new-friend', ({ payload }) => {
        console.info('new-friend', payload)
        commit('setFriend', state.friend.concat(payload))
      })
    },

    /**
     * 新私发聊天消息
     * @param {*} param0
     * @param {*} payload
     */
    handleNewMsg({ commit, state, rootState }, payload) {
      const uInfo = rootState.user.userInfo
      const msgMap = state.msgMap
      const partnerId = +payload.s_user === +uInfo.id
        ? payload.r_user
        : payload.s_user

      msgMap[partnerId] = msgMap[partnerId] || []
      msgMap[partnerId] = msgMap[partnerId].concat([payload])
      const current = state.chatList.find(el => +el.partner_id === +partnerId)

      if (current) {
        // 存在 => 更新
        Object.assign(current, {
          content: payload.content,
          create_time: payload.create_time
        })
      } else {
        // 不存在 => 向数组中添加一条记录
        state.chatList.unshift(payload)
      }

      commit('setMsgMap', JSON.parse(JSON.stringify(msgMap)))
      commit('setChatList', JSON.parse(JSON.stringify(state.chatList)))
    },

    /**
     * 新群组消息
     * @param {*} param0
     * @param {*} payload
     */
    handleRoomNewMsg({ commit, state }, payload) {
      const msgMap = state.msgMap
      const partnerId = payload.room_id
      msgMap[partnerId] = msgMap[partnerId] || []
      msgMap[partnerId] = msgMap[partnerId].concat([payload])
      const current = state.chatList.find(el => el.partner_id == partnerId)

      if (current) {
        // 存在 => 更新
        Object.assign(current, {
          content: payload.content,
          create_time: payload.create_time
        })
      } else {
        // 不存在 => 向数组中添加一条记录
        state.chatList.unshift(payload)
      }

      commit('setMsgMap', JSON.parse(JSON.stringify(msgMap)))
      commit('setChatList', JSON.parse(JSON.stringify(state.chatList)))
    },

    /**
     * 添加好友申请
     * @param {*} param0
     * @param {*} param1
     */
    addFriendApply({ rootState }, { r_user }) {
      const uInfo = rootState.user.userInfo
      const payload = {
        remark: '',
        r_user: r_user,
        s_user: uInfo.id
      }
      socketInstance.emit('friendApply', { payload })
    },

    /**
     * @description 发送新消息
     * @param {String} param0
     * @param {String} param1
     */
    sendMsg({ rootState }, { r_user, content, room_id }) {
      const uInfo = rootState.user.userInfo
      if (!room_id) {
        socketInstance.emit('news', {
          payload: {
            content,
            r_user: r_user,
            s_user: uInfo.id,
            avatar: uInfo.avatar,
            nickname: uInfo.nickname
          }
        })
      } else {
        socketInstance.emit('room-news', {
          payload: {
            content,
            room_id,
            r_user: r_user,
            s_user: uInfo.id,
            avatar: uInfo.avatar,
            nickname: uInfo.nickname
          }
        })
      }
    },

    /**
     * 获取好友列表
     * @param {*} param0
     */
    getNewFriend({ commit, rootState }) {
      const uInfo = rootState.user.userInfo
      napi.getNewFriend({
        user_id: uInfo.id
      }).then(res => {
        commit('setNewFriend', res)
      })
    },

    /**
     * 处理好友申请
     * @param {*} _
     * @param {*} param1
     * status: 0 => 同意, 1 => 拒绝
     */
    dealFriendApply(_, { id, status }) {
      const payload = { id, status }
      socketInstance.emit('dealFriendApply', { payload })
    },

    /**
     * 获取好友列表
     * @param {*} param0
     */
    getFriendList({ commit, rootState }) {
      const uInfo = rootState.user.userInfo
      napi.getFriendList({
        user_id: uInfo.id
      }).then(res => {
        commit('setFriend', res)
      })
    }
  }
}
